
(function($, undefined) {


var defaults = {
    templates: { 
    	base: '<div class="lm-content" style="display:none; z-index:1031; position:fixed; left:50%;" />',
    	container: '<div class="lm-container" />',
    	message: '<div class="alert" />',
    	close: '<a href="#" />',
    	messages: {
        	defaultMsg: {
        		text: '<div style="text-align:center;">Chargement ...</div>',
        		typeClass: 'alert-warning'
        	},
        	error: {
        		text: 'Une erreur est survenue !',
        		typeClass: 'alert-danger'
        	},
        	success: {
        		text: 'Terminée !',
        		typeClass: 'alert-success'
        	}
        }
    },
    text: {
    	close: '×'
    },
    topStart: 0,
    distance: 60,
    heightMax:350
};


var lm = $.loaderManager = {};

$.fn.loaderManager = function(o) { return new lm.Loader(this,o); };

lm.Loader = function(manager, options) {
	var loader = this;
	
	// Chargement des paramètres
	this._options = $.extend(true, {},
			defaults,
			options
		);
	
	// Variables
    this.locker = new Array();
	this.isStart = false;
	this.isAnimated = false;
	this.countMessage = 0;
    
    // events
    this.onStart = function(){};
    this.onProcess = function(){};
    this.onFinish = function(){};
    
    this._messages = {};
    
    this._container;
    this._content;
    
    manager.each(function(i, _element) {
		var element = $(_element);
		loader._content = loader._renderLoader(element);
		element.data('loader', loader);
	});
	
	return this;	
};

lm.Loader.prototype = {
	// Fonctions internes
	_renderLoader: function(element){
		var loader;
		
		if(this._content){
			loader = this._content;
			loader.css('margin-left', '-'+(this._content.width()/2)+'px');
		} else {
			loader = $(this._options.templates.base).prependTo(element);
			loader.css('opacity', 0);
			
			this._container = $(this._options.templates.container).appendTo(loader);
			this._container.css('max-height', this._options.heightMax+'px');
		}
		
		return loader;
	},
	
	_renderMessage: function(message){
		var element = $(this._options.templates.message).appendTo(this._container);
		
		element
			.addClass(message.typeClass)
			.html(message.text);
		
		return element;
	},
	
	// Fonctions public
	setTemplateMessage: function(type, text, typeClass){
		if(typeof this._options.templates.messages[type] == 'undefined')
			this._options.templates.messages[type] = {};
			
		this._options.templates.messages[type].text = text;
		this._options.templates.messages[type].typeClass = typeClass;
	},
	
	addMessage: function(type, text, typeClass){
		
		if(typeof text != 'undefined' && typeof typeClass != 'undefined')
			this.setTemplateMessage(type, text, typeClass);
		else if(typeof type == 'undefined')
			type = 'defaultMsg';
		
		var message = {
			id:	this.countMessage,
			type:type,
			text:this._options.templates.messages[type].text,
			typeClass:this._options.templates.messages[type].typeClass,
			
			callBack: function(){}
		};

		message['element'] = this._renderMessage(message);
		
		this._messages[this.countMessage] = message;
		this.countMessage++;

		this._renderLoader();
		
		return message;
	},
	
    start: function(type, text, typeClass){
    	var message;
    	
    	if(this.isStart){
    		console.log('loader deja lancé');
    		message = $('<div>loader deja lancé</div');
    	} else {
    		this._content
    			.hide()
    			.css('top', this._options.topStart);
    		    		    		
    		this.isStart = true;
    		this.isAnimated = true;

    		if(typeof type == 'number'){
    			var idMsg = type;
    			message = this.getMessage(idMsg);
    		} else
    			message = this.addMessage(type, text, typeClass);
    		this.onStart();
    		
    		this._content
    			.show()
    			.animate({
				    opacity: 1,
				    top: '+='+this._options.distance
				}, 300, function() { this.isAnimated = false; });
    		
    	}
    	
		return message;
    },
    hide: function(erreur){
    	var loader = this._loader;
    	if($('#mainTopLoader').size() != 0 && parseInt(this._loader.css('top')) > 0){
    		if(typeof erreur == 'undefined'){
	    		this.setContent('Terminé !');
				$('#contentLoader', loader).removeClass('alert-warning');
				$('#contentLoader', loader).addClass('alert-success');
	    		setTimeout(function(){
	    			loader.animate({
		    			opacity: 0,
					    top: '-=70'
					}, 300, function() {});
	    		},1000);
    		} else {
    			this.setContent(erreur);
				$('#contentLoader', loader).removeClass('alert-warning');
				$('#contentLoader', loader).addClass('alert-error');
	    		setTimeout(function(){
	    			loader.animate({
		    			opacity: 0,
					    top: '-=70'
					}, 300, function() {});
	    		},10000);
    		}
    	}
    },
    lock: function(signName){
    	if(this.locker.indexOf(signName) >= 0)
    		return true;
    	
    	this.locker.push(signName);
    	return false;
    },
    unlock: function(signName){
    	if(this.locker.indexOf(signName) >= 0)
    		this.locker.splice(this.locker.indexOf(signName),1);
    }   
};

})(jQuery);